﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Globalization;
using System.Reflection;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace UtilityLibrary.Ormapping
{
	public class AttributeAdapter2
	{
		protected Database DataBase { get; private set; }

		#region  构造函数

		public AttributeAdapter2()
		{
			DatabaseProviderFactory factory = new DatabaseProviderFactory();
			DataBase = factory.CreateDefault();
		}

		public AttributeAdapter2(string configName)
		{
			DatabaseProviderFactory factory = new DatabaseProviderFactory();
			DataBase = factory.Create(configName);
		}

		#endregion

		/// <summary>
		/// 查询列表，绑定模型列表
		/// </summary>
		/// <typeparam name="T">模型类别</typeparam>
		/// <param name="procName">存储过程名称</param>
		/// <returns>模型列表</returns>
		public IList<T> Select<T>(string procName)
		{
			using (IDataReader reader = DataBase.ExecuteReader(procName))
			{
				return MappingList<T>(reader);
			}
		}

		/// <summary>
		/// 查询列表，绑定模型列表
		/// </summary>
		/// <typeparam name="T">模型类别</typeparam>
		/// <param name="cmdType">命令类别</param>
		/// <param name="query">命令请求</param>
		/// <returns>模型列表</returns>
		public IList<T> Select<T>(CommandType cmdType, string query)
		{
			using (IDataReader reader = DataBase.ExecuteReader(cmdType, query))
			{
				return MappingList<T>(reader);
			}
		}

		/// <summary>
		/// 根据sql语句查询列表，绑定模型列表
		/// </summary>
		/// <typeparam name="T">模型类别</typeparam>
		/// <param name="sqlCmd">包含参数的命令对象</param>
		/// <returns>模型列表</returns>
		public IList<T> Select<T>(DbCommand sqlCmd)
		{
			using (IDataReader reader = DataBase.ExecuteReader(sqlCmd))
			{
				return MappingList<T>(reader);
			}
		}

		/// <summary>
		/// 查询数据，绑定模型
		/// </summary>
		/// <typeparam name="T">模型类别</typeparam>
		/// <param name="sql">存储过程名称</param>
		/// <returns>模型</returns>
		public T GetDetails<T>(string procName)
		{
			using (IDataReader reader = DataBase.ExecuteReader(procName))
			{
				IList<T> tlist = MappingList<T>(reader);
				if (tlist == null) return default(T);
				if (tlist.Count <= 0) return default(T);
				return tlist[0];
			}
		}

		/// <summary>
		/// 查询数据，绑定模型
		/// </summary>
		/// <typeparam name="T">模型类别</typeparam>
		/// <param name="cmdType">命令类别</param>
		/// <param name="query">命令请求</param>
		/// <returns>模型</returns>
		public T GetDetails<T>(CommandType cmdType, string query)
		{
			using (IDataReader reader = DataBase.ExecuteReader(cmdType, query))
			{
				IList<T> tlist = MappingList<T>(reader);
				if (tlist == null) return default(T);
				if (tlist.Count <= 0) return default(T);
				return tlist[0];
			}
		}

		/// <summary>
		/// 查询数据，绑定模型
		/// </summary>
		/// <typeparam name="T">模型类别</typeparam>
		/// <param name="sqlCmd">包含参数的命令对象</param>
		/// <returns>模型</returns>
		public T GetDetails<T>(DbCommand sqlCmd)
		{
			using (IDataReader reader = DataBase.ExecuteReader(sqlCmd))
			{
				IList<T> tlist = MappingList<T>(reader);
				if (tlist == null) return default(T);
				if (tlist.Count <= 0) return default(T);
				return tlist[0];
			}
		}

		#region 似有函数

		/// <summary>
		/// 映射datareader到模型列表
		/// </summary>
		/// <typeparam name="T">模型类型</typeparam>
		/// <param name="reader">datareader</param>
		/// <returns>列表</returns>
		private IList<T> MappingList<T>(IDataReader reader)
		{
			if (reader == null) return null;

			IList<T> tlist = new List<T>();
			while (reader.Read())
			{
				//创建对象实例
				Object obj = Activator.CreateInstance(typeof(T));

				//为属性赋值
				foreach (PropertyInfo p in typeof(T).GetProperties())
				{
					try
					{
						if (reader[p.Name] != DBNull.Value)
						{
							Object value = Convert.ChangeType(reader[p.Name], p.PropertyType, CultureInfo.CurrentCulture);
							p.SetValue(obj, value, null);
						}
					}
					catch (IndexOutOfRangeException)
					{
					}
				}

				//加入集合
				tlist.Add((T)obj);
			}

			return tlist;
		}

		#endregion
	}
}
